// ==UserScript==
// @name          NaNoWriMo Tools for Google Documents
// @namespace     tag:georgefox.edu,2005:pvandebr
// @description   A script to help automate the NaNoWriMo writing process by automatically posting word counts back to the NaNoWriMo servers when you save your document.  Also includes a locally updated daily meter, to keep you writing to meet your goal!
// @include       http://docs.google.com/Doc*
// @include       http://docs.google.com/Edit*
// @author        Pieter Vande Bruggen
// @version       1.5
// ==/UserScript==

var logged_in = false;
var nanowrimo_status = "";
var nanowrimo_daily = "";
var yesterdays_count = 0;
var days_left = 31 - new Date().getDate();
var progress_bar;

// First we need to force a check for the document we're intending to update
// stats about.  Ideally this would be accomplished through tags, but for
// some reason, Google seems to have omitted the display and editing of 
// tags from inside the document editing interface itself.  While this is
// probably not a bad move, it's a little awkward.
if (document.getElementById('txtTitle').innerHTML.match(/\[nanowrimo\]/i))
{
	// Next we'll set up our user interface elements...
	var doc_settings = document.evaluate('/HTML[1]/BODY[1]/FORM[1]/DIV[4]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/TABLE[1]/TBODY[1]/TR[1]/TD[2]/TABLE[1]/TBODY[1]/TR[1]/TD[1]/A[1]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;
	var doc_toolbar = document.getElementById('mainToolbar');
	
	nanowrimo_status = document.createElement("span");
	nanowrimo_status.innerHTML = '<span id="nanowrimo-status" style="color:#777; font-size: 0.8em">Verifying NaNoWriMo Status...</span>  | ';
	doc_settings.parentNode.insertBefore(nanowrimo_status, doc_settings);
	nanowrimo_status = nanowrimo_status.childNodes[0];
	
	nanowrimo_daily = document.createElement("td");
	doc_toolbar.width = "100%";
	doc_toolbar.childNodes[1].firstChild.lastChild.previousSibling.style.textAlign = "left";
	nanowrimo_daily.innerHTML = '<table width="100%"><tbody><tr><td style="text-align: right"><span id="nanowrimo-daily" style="color:#007; font-size:0.8em">Hello NaNoWriMo</span></td></tr></tbody></table>';
	doc_toolbar.childNodes[1].firstChild.appendChild(nanowrimo_daily);
	nanowrimo_daily = document.getElementById('nanowrimo-daily');
	
	document.getElementById('CollideNoWarning').innerHTML = "<img id='nanowrimo_progress_bar' />"
	progress_bar = document.getElementById('nanowrimo_progress_bar');

	// Verify that we are logged in to NaNoWriMo.org	
	GM_xmlhttpRequest({
		method: 'GET',
		url: 'http://www.nanowrimo.org/user.php',
		headers: {
			'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
			'Accept': 'application/atom+xml,application/xml,text/xml'
		},
		onload: function(x) { check_logged_in(x); get_yesterdays_count(); }
	});
	
	// Attach our local word count to the "Save" button.
	var save_button = document.getElementById('SaveButtonOn');
	save_button.addEventListener('click', update_word_count, true);
	
	// Attach our novel upload behavior to the "Save & close" button.
	var done_button = document.getElementById('DoneButton');
	done_button.addEventListener('click', upload_word_count, true);
	
	// Bind our daily word count updater to keypresses!
	document.getElementById('wys_frame').contentDocument.addEventListener("keydown", update_todays_count, true);
}

function update_word_count(e)
{
	var wc = count_words();
	
	if (logged_in) 
	{
		nanowrimo_status.innerHTML = "Updating word count...";
		
		GM_xmlhttpRequest({
			method: 'POST',
			url: 'http://www.nanowrimo.org/modules/wordcount/index.php',
			headers: {
				'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
				'Accept': '',
				'Content-type':  'application/x-www-form-urlencoded'
			},
			data: "wordcount="+wc+"&op=update",
			onload: function(x) { nanowrimo_status.innerHTML = "Word count updated: "+wc +" words"; }
		});
	}
	
	get_yesterdays_count();
	update_todays_count();
}

function upload_word_count(e)
{
	var novel = document.getElementById('wys_frame').contentDocument.body.textContent;
	var eschewed = novel.replace(/[a-zA-Z0-9]/g, 'a');
	
	if (logged_in)
	{
		nanowrimo_status.innerHTML = "Uploading novel...";
		
		GM_xmlhttpRequest({
			method: 'POST',
			url: 'http://www.nanowrimo.org/modules/wordcount/index.php',
			headers: {
				'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
				'Accept': '',
				'Content-type': 'multipart/form-data; boundary=nanowrimo-writely-updater' 
			},
			data: "--nanowrimo-writely-updater\r\n" +
			      "Content-Disposition: form-data; name=\"op\"\r\n\r\n" + 
			      "upload\r\n" +
			      "--nanowrimo-writely-updater\r\n" +
			      "Content-Disposition: form-data; name=\"MAX_FILE_SIZE\"\r\n\r\n" + 
			      (eschewed.length + 100) + "\r\n" +
			      "--nanowrimo-writely-updater\r\n" + 
			      "Content-Disposition: form-data; name=\"novelfile\"; filename=\"novel.txt\"\r\n" + 
			      "Content-Type: text/plain\r\n\r\n" + 
			      eschewed + "\r\n" +
			      "--nanowrimo-writely-updater--",
			onload: function(x) { nanowrimo_status.innerHTML = "Novel uploaded"; }
		});
	}
	
	update_todays_count();
}

function check_logged_in(x)
{
	logged_in = x.responseHeaders.match(/PHPSESSID/) ? x.responseText.match(/uid=(\d*)/)[1] : false;
	nanowrimo_status.innerHTML = x.responseHeaders.match(/PHPSESSID/) ? 
		"Logged in to NaNoWriMo" : 
		"Please log in to NaNoWriMo";
}

function get_yesterdays_count()
{
	if (logged_in) 
	{
		GM_xmlhttpRequest({
			method: 'GET',
			url: 'http://www.nanowrimo.org/modules/wcapi/wchistory.php?uid=' + logged_in,
			onload: function(x) 
			{ 
				yesterdays_count = x.responseText.match(/<wc>(\d*)<\/wc>/g); 
				yesterdays_count = yesterdays_count[yesterdays_count.length - 2];
				yesterdays_count = parseInt(yesterdays_count.substr(4, yesterdays_count.length - 4));
				update_todays_count(); 
			}
		});
	}
}

function update_todays_count()
{
	var todays_count = count_words() - yesterdays_count;
	avg_wpd = Math.ceil((50000 - yesterdays_count) / days_left);
	nanowrimo_daily.innerHTML = "You've written " + todays_count + " of your " + avg_wpd + " daily words.";
	
	progress_bar.src = "http://pinkness.freepgs.com/nanowrimo/meter.php?uid=131296&offset=-8";
}

function update_daily_words(evt)
{
	if (String.fromCharCode(evt.which || evt.charCode || evt.keyCode).match(/\s/)) update_todays_count();
}

function count_words()
{
	var novel = document.getElementById('wys_frame').contentDocument.body.textContent;
	return novel.split(/\s+/g).length;
}